<template>
    <BaseParam :label="label" :help="help">
        <div class="canvas-param">
            <div class="canvas-container" ref="canvasContainer">
                <canvas
                    ref="canvasRef"
                    :width="config?.width || 300"
                    :height="config?.height || 300"
                    @mousedown="startDrawing"
                    @mousemove="draw"
                    @mouseup="stopDrawing"
                    @mouseleave="stopDrawing"
                />
            </div>
            <div class="canvas-tools">
                <el-button-group>
                    <el-button size="small" @click="clearCanvas">清空</el-button>
                    <el-button size="small" @click="undo" :disabled="!canUndo">撤销</el-button>
                </el-button-group>
                <el-color-picker v-model="strokeColor" size="small" />
                <el-slider
                    v-model="strokeWidth"
                    :min="1"
                    :max="20"
                    :step="1"
                    style="width: 120px"
                />
            </div>
        </div>
    </BaseParam>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue';
import BaseParam from './BaseParam.vue';
import type { ParamConfig } from './types';

const props = defineProps<{
    modelValue?: string;
    label: string;
    help?: string;
    config?: {
        width?: number;
        height?: number;
        background?: string;
    };
}>();

const emit = defineEmits<{
    (e: 'update:modelValue', value: string): void;
}>();

const canvasRef = ref<HTMLCanvasElement>();
const canvasContainer = ref<HTMLDivElement>();
const isDrawing = ref(false);
const strokeColor = ref('#000000');
const strokeWidth = ref(2);
const canUndo = ref(false);
const history = ref<ImageData[]>([]);

let lastX = 0;
let lastY = 0;

const getContext = () => {
    return canvasRef.value?.getContext('2d');
};

const startDrawing = (event: MouseEvent) => {
    const ctx = getContext();
    if (!ctx || !canvasRef.value) return;

    isDrawing.value = true;
    const rect = canvasRef.value.getBoundingClientRect();
    lastX = event.clientX - rect.left;
    lastY = event.clientY - rect.top;

    // 保存当前状态用于撤销
    saveState();
};

const draw = (event: MouseEvent) => {
    const ctx = getContext();
    if (!isDrawing.value || !ctx || !canvasRef.value) return;

    const rect = canvasRef.value.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;

    ctx.beginPath();
    ctx.strokeStyle = strokeColor.value;
    ctx.lineWidth = strokeWidth.value;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(x, y);
    ctx.stroke();

    lastX = x;
    lastY = y;

    // 触发更新
    updateValue();
};

const stopDrawing = () => {
    isDrawing.value = false;
};

const clearCanvas = () => {
    const ctx = getContext();
    if (!ctx || !canvasRef.value) return;

    saveState();
    ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);
    updateValue();
};

const undo = () => {
    if (history.value.length > 0) {
        const ctx = getContext();
        if (!ctx) return;

        const lastState = history.value.pop();
        if (lastState) {
            ctx.putImageData(lastState, 0, 0);
            updateValue();
        }
        canUndo.value = history.value.length > 0;
    }
};

const saveState = () => {
    const ctx = getContext();
    if (!ctx || !canvasRef.value) return;

    const imageData = ctx.getImageData(0, 0, canvasRef.value.width, canvasRef.value.height);
    history.value.push(imageData);
    canUndo.value = true;
};

const updateValue = () => {
    if (!canvasRef.value) return;
    emit('update:modelValue', canvasRef.value.toDataURL());
};

onMounted(() => {
    if (props.modelValue) {
        const img = new Image();
        img.onload = () => {
            const ctx = getContext();
            if (!ctx || !canvasRef.value) return;
            ctx.drawImage(img, 0, 0);
        };
        img.src = props.modelValue;
    }
});
</script>

<style lang="scss" scoped>
.canvas-param {
    .canvas-container {
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        overflow: hidden;
        margin-bottom: 12px;

        canvas {
            display: block;
            background: #fff;
            cursor: crosshair;
        }
    }

    .canvas-tools {
        display: flex;
        align-items: center;
        gap: 12px;
    }
}
</style> 